#include "dht11.h"
#include "TIM4_Delay.h"

// 微秒级延迟
//static void delay_us(__IO uint32_t xus)
//{ 
//    uint32_t i;
//    SysTick_Config(72);  // 72mhz，72分频(1us中断一次)
//    for(i=0; i<xus; i++)
//    {
//        while(!(SysTick->CTRL & (SysTick_CTRL_COUNTFLAG)));
//        //第16位为1时，重装完成一次
//    }
//    // 第0位为0，关闭定时器
//    SysTick->CTRL &= ~(SysTick_CTRL_ENABLE<<SysTick_CTRL_ENABLE_Pos);
//}

//// 毫秒级延迟
//static void delay_ms(uint32_t xms)
//{
//    while(xms--)
//    {
//        delay_us(1000);
//    }
//}

void DHT11_Init(void)
{
    DHT11_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_Initstruct;
    GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Initstruct.GPIO_Pin = DHT11_Pin;
    GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_Port,&GPIO_Initstruct);
    DHT_PIN_H(); // 空闲高电平 
    TIM4_DelayInit();
}


// dht11起始帧,成功返回0,失败返回1
uint8_t DHT11_Start(void)
{
    uint8_t cnt = 0;
    DHT_OUT();
    DHT_PIN_L();
    TIM4_Delayms(20);
    DHT_PIN_H();
    TIM4_Delayus(30);
    DHT_IN();
    while(!DHT_PIN_READ && cnt<100)
    {
        cnt++;
        TIM4_Delayus(1);
    }
    if(cnt>=100)
        return 1;
    else    
        cnt = 0;
    while(DHT_PIN_READ && cnt<100)
    {
        cnt++;
        TIM4_Delayus(1);
    }
    if(cnt>=100)
        return 1;
    else 
        return 0;
}


// 读取一位数据
uint8_t DHT_ReadBit(void)
{
    while(DHT_PIN_READ);
    while(!DHT_PIN_READ);
    TIM4_Delayus(35);
    if(DHT_PIN_READ)
        return 1;
    else
        return 0;
}

// 读取一个字节数据
uint8_t DHT_ReadByte(void)
{
    uint8_t tmp;
    uint8_t Byte = 0x00;
    for(tmp=0x80;tmp!=0;tmp>>=1)
    {
        if(DHT_ReadBit())
        {
            Byte |= tmp;
        }
        else
        {
            Byte &=~tmp;
        }
    }
    return Byte;
}

// 读取五个字节数据，成功返回0，失败返回1
uint8_t DHT_GetValue(DHT_DAT *Val)
{
    uint8_t SUM;
    DHT11_Start(); 
    Val->HUMI_INT = DHT_ReadByte();
    Val->HUMI_DEC = DHT_ReadByte();
    Val->TEMP_INT = DHT_ReadByte();
    Val->TEMP_DEC = DHT_ReadByte();
    Val->CRC_NUM = DHT_ReadByte();
    SUM = Val->HUMI_INT+Val->HUMI_DEC+Val->TEMP_INT+Val->TEMP_DEC;

    if(SUM==Val->CRC_NUM)
        return 0;
    else   
        return 1;
}
